package com.lancoo.cvas.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lancoo.cvas.aspect.LogAnnotation;
import com.lancoo.cvas.entity.*;
import com.lancoo.cvas.pojo.common.Deleted;
import com.lancoo.cvas.pojo.common.PageInfo;
import com.lancoo.cvas.pojo.vo.*;
import com.lancoo.cvas.service.*;
import com.lancoo.cvas.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

@Api(tags = "选课设置")
@RestController
@RequestMapping("/api/v5.0.1/web/selectCourse")
public class PreSelectController {

    @Resource
    private CssTaskInfoService cssTaskInfoService;

    @Resource
    private CourseService courseService;

    @Resource
    private TeachingClassService teachingClassService;

    @Resource
    private StudentService studentService;

    @Resource
    private PlanTeachingService planTeachingService;
    @Resource
    private TaskInfoService taskInfoService;

    @ApiOperation("获取选课任务")
    @GetMapping(value = "/cs/getCssTask")
    @LogAnnotation(operationType = "3", operationContent = "获取选课任务")
    public Result<CssTaskInfo> getCssTask(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId) {
        return Result.ofSuccess(cssTaskInfoService.getCssTaskInfo(taskId));
    }

    @ApiOperation("是否可以修改轮次")
    @GetMapping(value = "/cs/getEarliestRound")
    @LogAnnotation(operationType = "3", operationContent = "是否可以修改轮次")
    public Result<Boolean> getEarliestRound(@ApiParam(value = "选课 id", required = true) @RequestParam Integer cssTaskId) {
        return Result.ofSuccess(cssTaskInfoService.getEarliestRound(cssTaskId));
    }

    @ApiOperation("批量删除轮次")
    @DeleteMapping(value = "/cs/removeUselessRound")
    @LogAnnotation(operationType = "4", operationContent = "批量删除轮次")
    public Result<Boolean> removeUselessRound(@ApiParam(value = "选课 id", required = true) @RequestParam Integer cssTaskId,
                                              @ApiParam(value = "轮次 1正 2补 3退", required = true) @RequestBody List<Integer> selectRound) {
        return Result.ofSuccess(cssTaskInfoService.removeUselessRound(cssTaskId, selectRound));
    }

    @ApiOperation("设置选课轮次/选课任务")
    @PostMapping(value = "/cs/setCssTask")
    @LogAnnotation(operationType = "2", operationContent = "设置选课轮次/选课任务")
    public Result<CssTaskInfo> setCssTask(@ApiParam(value = "选课任务实体类", required = true) @RequestBody CssTaskInfoInput cssTaskInfoInput) {
        CssTaskInfo cssTaskInfo = new CssTaskInfo();
        //类型转换
        BeanUtil.copyProperties(cssTaskInfoInput, cssTaskInfo);
        return Result.ofSuccess(cssTaskInfoService.updateCssTaskInfo(cssTaskInfo));
    }


    @ApiOperation("根据选课id和轮次获取所有选课轮次")
    @GetMapping(value = "/cs/getCssTaskRound")
    @LogAnnotation(operationType = "3", operationContent = "根据选课id和轮次获取所有选课轮次")
    public Result<List<CssTaskRound>> getCssTaskRound(@ApiParam(value = "选课 id", required = true) @RequestParam Integer cssTaskId,
                                                      @ApiParam(value = "轮次 1正 2补 3退", required = true) @RequestParam Integer selectRound) {
        return Result.ofSuccess(cssTaskInfoService.getCssTaskRound(cssTaskId, selectRound));
    }


    @ApiOperation("更新或添加选课轮次")
    @PostMapping(value = "/cs/addOrUpdateCssTaskRound")
    @LogAnnotation(operationType = "2", operationContent = "更新或添加选课轮次")
    public Result<CssTaskRound> addOrUpdateCssTaskRound(@ApiParam(value = "选课轮次实体类", required = true) @RequestBody CssTaskRound cssTaskRound) {
        return Result.ofSuccess(cssTaskInfoService.addOrUpdateCssTaskRound(cssTaskRound));
    }

    @ApiOperation("更新或添加选课轮次")
    @PostMapping(value = "/cs/addOrUpdateCssTaskRoundWX")
    @LogAnnotation(operationType = "2", operationContent = "更新或添加选课轮次")
    public Result<CssTaskRound> addOrUpdateCssTaskRoundWX(@ApiParam(value = "选课轮次实体类", required = true) @RequestBody CssTaskRound cssTaskRound) {
        return Result.ofSuccess(cssTaskInfoService.addOrUpdateCssTaskRoundWX(cssTaskRound));
    }

    @ApiOperation("获取课程范围")
    @PostMapping(value = "/cs/getCourseRange")
    @LogAnnotation(operationType = "3", operationContent = "获取课程范围")
    public Result<CourseRange> getCourseRange(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                              @ApiParam(value = "选课轮次实体类", required = true) @RequestBody List<String> gradeIds) {
        return Result.ofSuccess(cssTaskInfoService.getCourseRange(taskId, gradeIds));
    }

    @ApiOperation("获取课程范围")
    @GetMapping(value = "/cs/getRange")
    @LogAnnotation(operationType = "3", operationContent = "获取课程范围")
    public Result<List<CssRangeDTO>> getRange(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                              @ApiParam(value = "对应选课id", required = false) @RequestParam(required = false) Long cssTaskId,
                                              @ApiParam(value = "flag 轮次 1正 2补 3退", required = false) @RequestParam(required = false) Integer flag) {
        return Result.ofSuccess(cssTaskInfoService.getRange(taskId, cssTaskId, flag));
    }

    @ApiOperation("设置选课范围")
    @PostMapping(value = "/cs/setRange")
    @LogAnnotation(operationType = "2", operationContent = "设置选课范围")
    public Result<List<CssRange>> setRange(@ApiParam(value = "选课范围实体类", required = true) @RequestBody List<CssRange> cssRanges,
                                           @ApiParam(value = "轮次阶段id", required = true) @RequestParam Integer roundId) {
        return Result.ofSuccess(cssTaskInfoService.setRange(cssRanges, roundId));
    }


    @ApiOperation("删除选课轮次")
    @DeleteMapping(value = "/cs/removeCssTaskRound")
    @LogAnnotation(operationType = "4", operationContent = "删除选课轮次")
    public Result<Boolean> removeCssTaskRound(@ApiParam(value = "轮次阶段id", required = true) @RequestParam Integer roundId) {
        return Result.ofSuccess(cssTaskInfoService.removeCssTaskRound(roundId));
    }


    @ApiOperation("判断上下学期")
    @DeleteMapping(value = "/cs/checkTheNextTerm")
    @LogAnnotation(operationType = "3", operationContent = "判断上下学期")
    public Result<Boolean> checkTheNextTerm(@ApiParam(value = "轮次阶段id", required = true) @RequestHeader Integer taskId) {

        TaskInfo taskInfo = taskInfoService.getById(taskId);

        return Result.ofSuccess(taskInfo.getOpenType().equals(0));

    }

    @GetMapping("/getCourseList")
    @ApiOperation("获取所有选课课程")
    @LogAnnotation(operationType = "3", operationContent = "获取所有选课课程")
    public Result<List<Course>> getCourseList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId) {
        return Result.ofSuccess(cssTaskInfoService.getCourseList(taskId));
    }


    @ApiOperation("确定选课结果-在线选课教学班列表")
    @GetMapping(value = "/getSelectionTeachingClass")
    @LogAnnotation(operationType = "3", operationContent = "确定选课结果-在线选课教学班列表")
    public Result<PageInfo<TeachingClassCourseDto>> getSelectionTeachingClass(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                              @ApiParam(value = "0已启用 1未启用  2正常开班 3人数不足 4 已取消  5 查全部", required = false) @RequestParam(required = false) Integer handleState,
                                                                              @ApiParam(value = "课程id 传null全部", required = false) @RequestParam(required = false) Long courseId,
                                                                              @ApiParam(value = "课程名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                                              @ApiParam(value = "最低开班人数", required = false) @RequestParam(required = false, defaultValue = "30") Integer minClassNum,
                                                                              @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                              @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<TeachingClassCourseDto> page = new Page<>(currentPage, pageSize);
        page.setOptimizeCountSql(false);
        return Result.ofSuccess(teachingClassService.getSelectionTeachingClass(page, taskId, handleState, courseId, keyWord, minClassNum));
    }


    @ApiOperation("发布选课结果-在线选课教学班列表")
    @GetMapping(value = "/getReleaseSelectionTeachingClass")
    @LogAnnotation(operationType = "3", operationContent = "发布选课结果-在线选课教学班列表")
    public Result<PageInfo<TeachingClassCourseDto>> getReleaseSelectionTeachingClass(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                                     @ApiParam(value = "0已启用 1未启用  2正常开班 3人数不足 4 已取消  5 查全部 6 拆班新增", required = false) @RequestParam(required = false) Integer handleState,
                                                                                     @ApiParam(value = "课程id 传null全部", required = false) @RequestParam(required = false) String gradeId,
                                                                                     @ApiParam(value = "课程id 传null全部", required = false) @RequestParam(required = false) Long majorId,
                                                                                     @ApiParam(value = "课程名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                                                     @ApiParam(value = "最低开班人数", required = false) @RequestParam(required = false, defaultValue = "30") Integer minClassNum,
                                                                                     @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                                     @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<TeachingClassCourseDto> page = new Page<>(currentPage, pageSize);
        page.setOptimizeCountSql(false);
        return Result.ofSuccess(teachingClassService.getReleaseSelectionTeachingClass(page, taskId, handleState, gradeId, majorId, keyWord, minClassNum));
    }


    @ApiOperation("批量修改教学班状态")
    @PostMapping(value = "/withdraw")
    @LogAnnotation(operationType = "2", operationContent = "批量修改教学班状态")
    public Result<Object> updateTeacherPlan(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                            @ApiParam(value = "教学班id,逗号分割", required = true) @RequestParam String teachingClassIds,
                                            @ApiParam(value = "0不可用-取消班级 1可用-正常开班 2未设置-撤回", required = true) @RequestParam Integer isEnable) {
        if (StrUtil.isBlank(teachingClassIds)) {
            return Result.ofFail("教学班id不能为空");
        }
        String[] split = teachingClassIds.split(",");
        List<Long> teachingClassIdList = new ArrayList<>();
        for (String s : split) {
            teachingClassIdList.add(Long.parseLong(s));
        }
        teachingClassService.updateTeachingClassEnable(teachingClassIdList, isEnable);
        return Result.ofSuccess("修改成功");
    }


    @ApiOperation("根据教学班id获取学生列表")
    @GetMapping(value = "/getStudentListByTeachingClassId")
    @LogAnnotation(operationType = "3", operationContent = "根据教学班id获取学生列表")
    public Result<List<StudentByClass>> getStudentListByTeachingClassId(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                        @ApiParam(value = "教学班id", required = true) @RequestParam Long teachingClassId) {
        return Result.ofSuccess(studentService.getStudentListByTeachingClassId(taskId, teachingClassId));
    }


    @ApiOperation("根据教学班id获取学生列表")
    @GetMapping(value = "/getStudentsByTeachingClassId")
    @LogAnnotation(operationType = "3", operationContent = "根据教学班id获取学生列表")
    public Result<PageInfo<Student>> getStudentsByTeachingClassId(@ApiParam(value = "教学班id", required = true) @RequestParam Long teachingClassId,
                                                                  @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                  @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<Student> page = new Page<>(currentPage, pageSize);
        page.setOptimizeCountSql(false);
        return Result.ofSuccess(studentService.getStudentsByTeachingClassId(page, teachingClassId));
    }

    @ApiOperation("获取一个课程的学生<不包含该课程已选学生>")
    @GetMapping(value = "/getStudentListByCourse")
    @LogAnnotation(operationType = "3", operationContent = "获取一个课程的学生<不包含该课程已选学生>")
    public Result<List<StudentGroupClass>> getStudentListByCourse(@ApiParam(value = "1课程  2环节", required = true) @RequestParam(required = true) Integer flag,
                                                                  @ApiParam(value = "课程id", required = true) @RequestParam Long courseId,
                                                                  @ApiParam(value = "修读性质：1主修2辅修", required = true) @RequestParam Integer studyNature,
                                                                  @ApiParam(value = "true:显示全部 false:只显示未选", required = true) @RequestParam(defaultValue = "false") boolean isDisplaySelected,
                                                                  @ApiParam(value = "校区id", required = false) @RequestParam(required = false) String campusId) {
        return Result.ofSuccess(planTeachingService.getStudentListByCourse(flag, courseId, studyNature, campusId, isDisplaySelected));
    }


    @ApiOperation("同课程合班")
    @PostMapping(value = "/mixedClassByCourse")
    @LogAnnotation(operationType = "2", operationContent = "同课程合班")
    public Result<Boolean> mixedClassByCourse(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                              @ApiParam(value = "合班的教学班id", required = true) @RequestBody List<Long> teachingClassIds) {
        return Result.ofSuccess(planTeachingService.mixedClassByCourse(taskId, teachingClassIds));
    }


    @ApiOperation("获取一个课程辅修的学生")
    @GetMapping(value = "/getMinorStudentByCourseId")
    @LogAnnotation(operationType = "3", operationContent = "获取一个课程辅修的学生")
    public Result<List<Student>> getMinorStudentByCourseId(@ApiParam(value = "课程id", required = true) @RequestParam(required = true) Long courseId) {
        return Result.ofSuccess(planTeachingService.getMinorStudentByCourseId(courseId));
    }


    @ApiOperation("批量设置教学班学生")
    @PostMapping(value = "/batchSetStudent")
    @LogAnnotation(operationType = "2", operationContent = "批量设置教学班学生")
    public Result<List<TeachingClassStudent>> batchAddStudent(@ApiParam(value = "退选实体类", required = true) @RequestBody BatchSetStudent batchSetStudent) {
        return Result.ofSuccess(studentService.batchAddStudent(batchSetStudent));
    }


    @ApiOperation("统计-发布选课结果")
    @GetMapping(value = "/preStatistics")
    @LogAnnotation(operationType = "3", operationContent = "获取统计-发布选课结果")
    public Result<PublishStatisticsPre> preStatistics(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                      @ApiParam(value = " 1在线选课", required = true) @RequestParam Integer teachingClassType,
                                                      @ApiParam(value = "最低开班人数", required = false) @RequestParam(required = false, defaultValue = "30") Integer minClassNum) {
        return Result.ofSuccess(teachingClassService.preStatistics(taskId, teachingClassType, minClassNum));
    }


    @ApiOperation("获取重修相关结果")
    @GetMapping(value = "/getRelatedClassInfo")
    @LogAnnotation(operationType = "3", operationContent = "获取重修相关结果")
    public Result<RelatedNum> getRelatedClassInfo(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                  @ApiParam(value = "对应学校id", required = true) @RequestParam String schoolId,
                                                  @ApiParam(value = "对应学期", required = false) @RequestParam(required = false) String term) {
        return Result.ofSuccess(teachingClassService.getRelatedClassInfo(taskId, schoolId, term));
    }


    @ApiOperation("统计-退选统计")
    @GetMapping(value = "/cs/deselectStatistics")
    @LogAnnotation(operationType = "3", operationContent = "获取统计-退选统计")
    public Result<PublishDeselectStatistic> csStatistics(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId) {
        return Result.ofSuccess(teachingClassService.getDeselectStatistic(taskId));
    }


    @ApiOperation("修改任务阶段状态/整个流程结束才需要修改")
    @GetMapping(value = "taskProgress/update")
    @LogAnnotation(operationType = "2", operationContent = "修改任务阶段状态")
    public Result<Boolean> updateTaskProgress(@ApiParam(value = "任务流程id", required = true) @RequestParam Integer id,
                                              @ApiParam(value = "0未完成  1已完成", required = true) @RequestParam Integer finish) {
        return Result.ofSuccess();
    }


    @ApiOperation("导出在线选课")
    @GetMapping(value = "/cs/excel")
    @LogAnnotation(operationType = "14", operationContent = "导出在线选课")
    public void csToExcel(@ApiParam(value = "响应", required = false) HttpServletResponse response,
                          @ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                          @ApiParam(value = "0已启用 1未启用  2正常开班 3人数不足 4 已取消  5 查全部 6 拆班新增", required = false) @RequestParam(required = false) Integer handleState,
                          @ApiParam(value = "课程id 传null全部", required = false) @RequestParam(required = false) String gradeId,
                          @ApiParam(value = "年级名称", required = false) @RequestParam(required = false) String gradeName,
                          @ApiParam(value = "年级id", required = false) @RequestParam(required = false) Long majorId,
                          @ApiParam(value = "专业名称", required = false) @RequestParam(required = false) String majorName,
                          @ApiParam(value = "课程名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                          @ApiParam(value = "最低开班人数", required = false) @RequestParam(required = false, defaultValue = "30") Integer minClassNum,
                          @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                          @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        teachingClassService.csToExcel(response, taskId, handleState, gradeId, gradeName, majorId, majorName, keyWord, minClassNum, currentPage, pageSize);
    }


    @ApiOperation("获取退选列表")
    @GetMapping("/cs/getDeselectStudent")
    @LogAnnotation(operationType = "3", operationContent = "获取退选列表")
    public Result<PageInfo<StudentCourseVo>> getDeselectStudent(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                @ApiParam(value = "专业id ", required = false) @RequestParam(required = false) String majorId,
                                                                @ApiParam(value = "年级id ", required = false) @RequestParam(required = false) String gradeId,
                                                                @ApiParam(value = "班级id", required = false) @RequestParam(required = false) String classId,
                                                                @ApiParam(value = "名称、学号模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                                @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<StudentCourseVo> page = new Page<>(currentPage, pageSize);
        return Result.ofSuccess(studentService.getDeselectStudent(taskId, page, majorId, gradeId, classId, keyWord));
    }

//    @ApiOperation("退选")
//    @RateLimiter(qps = 1)
//    @PostMapping(value = "/cancelCourse")
//    public Result<String> cancelCourse(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
//                                               @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
//                                               @ApiParam(value = "教学班id", required = true) @RequestParam Long teachingClassId,
//                                               @ApiParam(value = "2退选   3管理员移除", required = true) @RequestParam Integer flag) {
//        int res = studentService.cancelCourse(taskId, studentId, teachingClassId, flag);
//        switch (res) {
//            case 1:
//                return Result.ofSuccess("退选成功");
//            case -2:
//                return Result.ofFail(2, "Redis服务连接异常，请联系管理员");
//            case -4:
//                return Result.ofFail(2, "不存在该教学班");
//            default:
//                return Result.ofFail(2, "退选失败，请重试");
//        }
//    }


    @ApiOperation("获取学生已选课程")
    @GetMapping(value = "/preSelected")
    @LogAnnotation(operationType = "3", operationContent = "获取学生已选课程")
    public Result<List<StudentTeachingClass>> getSelectedTeachingClass(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                       @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                                       @ApiParam(value = "0无需选课 1在线选课;", required = true) @RequestParam Integer teachingClassType) {
        return Result.ofSuccess(studentService.getSelectedByStudentId(taskId, studentId, teachingClassType));
    }


    @ApiOperation("导出退选结果")
    @GetMapping(value = "/cs/des/excel")
    @LogAnnotation(operationType = "14", operationContent = "导出退选结果")
    public void deselectStudentToExcel(@ApiParam(value = "响应", required = false) HttpServletResponse response,
                                       @ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                       @ApiParam(value = "专业id ", required = false) @RequestParam(required = false) String majorId,
                                       @ApiParam(value = "专业名称 ", required = false) @RequestParam(required = false) String majorName,
                                       @ApiParam(value = "年级id ", required = false) @RequestParam(required = false) String gradeId,
                                       @ApiParam(value = "年级名称 ", required = false) @RequestParam(required = false) String gradeName,
                                       @ApiParam(value = "班级id", required = false) @RequestParam(required = false) String classId,
                                       @ApiParam(value = "班级名称", required = false) @RequestParam(required = false) String className,
                                       @ApiParam(value = "名称、学号模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                       @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                       @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        studentService.deselectStudentToExcel(response, taskId, majorId, majorName, gradeId, gradeName, classId, className, keyWord, currentPage, pageSize);
    }


}

